package gptma.bo.dao.task;

import gptma.bo.aop.Logged;
import gptma.bo.aop.NoResultFailProof;
import gptma.bo.dao.GenericDaoJpaImpl;
import gptma.bo.model.employee.Employee;
import gptma.bo.model.employee.Employee_;
import gptma.bo.model.task.Imputation;
import gptma.bo.model.task.Imputation_;
import gptma.bo.model.task.Task;
import gptma.bo.util.GptmaUtils;

import java.util.Date;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

@Logged
@NoResultFailProof
public class ImputationDaoImpl extends GenericDaoJpaImpl<Imputation, Long>
		implements ImputationDao {

	@Override
	@SuppressWarnings("unchecked")
	public List<Imputation> findImputations(Task task) {
		return em.createNamedQuery("Imputation.findImputations")
				.setParameter("task", task).getResultList();
	}

	@Override
	public Imputation findLastImputation(Task task) {
		return (Imputation) em.createNamedQuery("Imputation.findImputations")
				.setParameter("task", task).setMaxResults(1).getSingleResult();
	}

	@Override
	public List<Imputation> findImputationsFromDates(Employee employee,
			Date startDate, Date endDate, boolean between) {

		// reset time info on parameter so that query can be cached
		Date start = GptmaUtils.resetTimeInfo(startDate);
		Date end = GptmaUtils.resetTimeInfo(endDate);

		// cf. http://www.ibm.com/developerworks/java/library/j-typesafejpa/
		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<Imputation> query = builder.createQuery(Imputation.class);

		// FROM
		Root<Imputation> root = query.from(Imputation.class);

		// WHERE
		query.where(builder.and(
		// employee criteria
		// Note: (equal(root.get(Imputation_.employee), employee) does not work
				builder.equal(root.get(Imputation_.employee).get(Employee_.id),
						employee.getId()),

				// date criteria
				between ? builder.between(root.get(Imputation_.date), start,
						end) : builder.equal(root.get(Imputation_.date), start)));

		// ORDER BY
		query.orderBy(builder.asc(root.get(Imputation_.date)));

		// GO
		List<Imputation> ret = em.createQuery(query)
				.setHint(HIBERNATE_QUERY_CACHE, true).setMaxResults(10)
				.getResultList();

		return ret;
	}

}
